#include "statsxx/preprocess/Preprocessor.hpp"

// STL
#include <algorithm>                  // std::minmax_element()
#include <vector>                     // std::vector<>

// jScience
#include "jScience/linalg/Matrix.hpp" // Vector<>, Matrix<>


//
// DESC: Normalize data to lie in the range [0,1].
//
inline Vector<double> Preprocessor::normalize_data(
                                                   Vector<double> x
                                                   ) const
{
    if(this->init)
    {

        for(auto i = 0; i < x.size(); ++i)
        {
            if( this->x_max[i] != this->x_min[i] )
            {
                x(i) = (x(i) - x_min[i])/this->x_max_minus_min[i];
            }
            else
            {
                x(i) = 0.5;
            }
        }

    }

    return x;
}

inline Matrix<double> Preprocessor::normalize_data(
                                                   Matrix<double> X
                                                   ) const
{
    if(this->init)
    {

        // TODO: NOTE: until we have a way of QUICKLY inserting rows/columns into a matrix, it is better to not have the Matrix<> version call the Vector<> version

        for( int i = 0; i < X.get_size(0); ++i )
        {
            for( int j = 0; j < X.get_size(1); ++j )
            {
                if( this->x_max[j] != this->x_min[j] )
                {
                    X(i,j) = (X(i,j) - x_min[j])/this->x_max_minus_min[j];
                }
                else
                {
                    X(i,j) = 0.5;
                }
            }
        }

    }

    return X;
}
